package ms.zuul.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StreamUtils;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE;

/**
 * Project Name: ms
 * File Name: MsSendErrorFilter
 * Package Name: ms.zuul.filter
 * Date: 2018/5/9  14:39
 * Copyright (c) 2018, tianyul All Rights Reserved.
 * 异常拦截器
 */
@Configuration
public class MsSendErrorFilter extends ZuulFilter {

    private Logger logger = Logger.getLogger(MsSendErrorFilter.class);
    @Override
    public String filterType() {
        return POST_TYPE;
    }

    @Override
    public int filterOrder() {
        return 2;
    }

    @Override
    public boolean shouldFilter() {
        // statusCode == 500 的时候执行
        RequestContext ctx = RequestContext.getCurrentContext();
        int statusCode = ctx.getResponseStatusCode();
        return statusCode == HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
    }

    @Override
    public Object run() {
        //获取请求上下文
        RequestContext ctx = RequestContext.getCurrentContext();

        //获取数据的流
        InputStream stream = ctx.getResponseDataStream();

        //转换成json
        String responseData;
        try {
            responseData = StreamUtils.copyToString(stream, Charset.forName("UTF-8"));
        } catch (IOException e) {
            logger.error("getResponseDataStream fail!", e);
            throw new RuntimeException("getResponseDataStream fail!", e);
        }
        // 将statusCode改为200
        ctx.setResponseStatusCode(HttpServletResponse.SC_OK);

        JSONObject expJsonObj = JSON.parseObject(responseData);

        //判断异常类型是否是自定义异常
        String expClazz = expJsonObj.getString("exception");
        if (StringUtils.equals("ms.common.exception.BizException", expClazz)) {

            String expMsg = expJsonObj.getString("message");
            JSONObject expMsgObj = JSON.parseObject(expMsg);
            String code = expMsgObj.getString("code");
            String errorMsg = expMsgObj.getString("errorMsg");

            MsResponseBody msResponseBody = new MsResponseBody(code, errorMsg);

            ctx.setResponseBody(JSON.toJSONString(msResponseBody));
        } else {
            String message = expJsonObj.getString("message");

            MsResponseBody msResponseBody = new MsResponseBody(ResponseCode.SYSTEM_EXCEPTION, message);
            ctx.setResponseBody(JSON.toJSONString(msResponseBody));
        }
        return null;
    }
}
